package cn.iocoder.yudao.module.system.controller.admin.zkdata;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.system.tcpserver.protocol1.ZkDataProcessService;
import cn.iocoder.yudao.module.system.tcpserver.pojo.HeartInfo;
import cn.iocoder.yudao.module.system.tcpserver.protocol2.NewZkDataProcessService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.system.controller.admin.zkdata.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.zkdata.ZkDataDO;
import cn.iocoder.yudao.module.system.service.zkdata.ZkDataService;

@Tag(name = "管理后台 - 数据纪录")
@RestController
@RequestMapping("/system/zk-data")
@Validated
public class ZkDataController {

    @Resource
    private ZkDataService zkDataService;

    @PostMapping("/create")
    @Operation(summary = "创建数据纪录")
    @PreAuthorize("@ss.hasPermission('system:zk-data:create')")
    public CommonResult<Long> createZkData(@Valid @RequestBody ZkDataSaveReqVO createReqVO) {
        return success(zkDataService.createZkData(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新数据纪录")
    @PreAuthorize("@ss.hasPermission('system:zk-data:update')")
    public CommonResult<Boolean> updateZkData(@Valid @RequestBody ZkDataSaveReqVO updateReqVO) {
        zkDataService.updateZkData(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除数据纪录")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('system:zk-data:delete')")
    public CommonResult<Boolean> deleteZkData(@RequestParam("id") Long id) {
        zkDataService.deleteZkData(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得数据纪录")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:zk-data:query')")
    public CommonResult<ZkDataRespVO> getZkData(@RequestParam("id") Long id) {
        ZkDataDO zkData = zkDataService.getZkData(id);
        return success(BeanUtils.toBean(zkData, ZkDataRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得数据纪录分页")
    @PreAuthorize("@ss.hasPermission('system:zk-data:query')")
    public CommonResult<PageResult<ZkDataRespVO>> getZkDataPage(@Valid ZkDataPageReqVO pageReqVO) {
        PageResult<ZkDataDO> pageResult = zkDataService.getZkDataPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, ZkDataRespVO.class));
    }

    @GetMapping("/devpage")
    @Operation(summary = "获得在线状态分页")
    @PreAuthorize("@ss.hasPermission('system:zk-data:query')")
    public CommonResult<PageResult<ZkDeviceDataVO>> getZkDevPage(@Valid ZkDataPageReqVO pageReqVO) {
        Map<String, HeartInfo> clientMap = ZkDataProcessService.clientMap;
        PageResult<ZkDeviceDataVO> result = new PageResult<>((long) clientMap.keySet().size());
        Map<String, HeartInfo> sortedMap2 = new TreeMap<>(clientMap);
        for (String s : sortedMap2.keySet()) {
            HeartInfo heartInfo = sortedMap2.get(s);
            if (StrUtil.isNotEmpty(pageReqVO.getDataSender()) && !heartInfo.getSender().equals(pageReqVO.getDataSender())) {
                continue;
            }
            if (pageReqVO.getStatus() != null && (heartInfo.getFirstTime() == null ? 0 : 1) != pageReqVO.getStatus()) {
                continue;
            }
            result.getList().add(ZkDeviceDataVO.builder().deviceId(heartInfo.getSender())
                    .status(heartInfo.getFirstTime() == null ? 0 : 1)
                    .firstOnlineTime(heartInfo.getFirstTime())
                    .lastOnlineTime(heartInfo.getDateTime()).build());
        }

        //-------------------------------------------------

        Map<String, HeartInfo> clientMap2 = NewZkDataProcessService.clientMap;
        Map<String, HeartInfo> sortedMap22 = new TreeMap<>(clientMap2);
        for (String s : sortedMap22.keySet()) {
            HeartInfo heartInfo = sortedMap22.get(s);
            if (StrUtil.isNotEmpty(pageReqVO.getDataSender()) && !heartInfo.getSender().equals(pageReqVO.getDataSender())) {
                continue;
            }
            if (pageReqVO.getStatus() != null && (heartInfo.getFirstTime() == null ? 0 : 1) != pageReqVO.getStatus()) {
                continue;
            }
            result.getList().add(ZkDeviceDataVO.builder().deviceId(heartInfo.getSender())
                    .status(heartInfo.getFirstTime() == null ? 0 : 1)
                    .firstOnlineTime(heartInfo.getFirstTime())
                    .lastOnlineTime(heartInfo.getDateTime()).build());
        }
        return success(result);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出数据纪录 Excel")
    @PreAuthorize("@ss.hasPermission('system:zk-data:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportZkDataExcel(@Valid ZkDataPageReqVO pageReqVO,
                                  HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ZkDataDO> list = zkDataService.getZkDataPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "数据纪录.xls", "数据", ZkDataRespVO.class,
                BeanUtils.toBean(list, ZkDataRespVO.class));
    }

}
